package cn.wolfcode.shop.seckillserver.service.impl;

import cn.wolfcode.shop.common.exception.BusinessException;
import cn.wolfcode.shop.common.util.CodeMsg;
import cn.wolfcode.shop.goodsapi.domain.Good;
import cn.wolfcode.shop.goodsapi.feign.GoodsFeignApi;
import cn.wolfcode.shop.util.BaseKeyPrefix;
import cn.wolfcode.shop.redis.RedisService;
import cn.wolfcode.shop.seckillapi.domain.SeckillGood;
import cn.wolfcode.shop.seckillapi.service.ISeckillGoodService;
import cn.wolfcode.shop.seckillapi.vo.SeckillOrderVO;
import cn.wolfcode.shop.seckillserver.mapper.SeckillMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class SeckillGoodeServiceImpl implements ISeckillGoodService {

    @Autowired
    private SeckillMapper seckillMapper;

    @Autowired
    private GoodsFeignApi goodsFeignApi;

    @Autowired
    private RedisService redisService;

    /**
     * 查询秒杀订单列表
     * @return
     */
    @Override
    public List<SeckillOrderVO> query() {

        //获取redis 中的秒杀订单数据
        BaseKeyPrefix mapKey = new BaseKeyPrefix(0, "SECKILL_GOOD_HASH");
        Map<String, SeckillOrderVO> soMap = redisService.hgetAll(mapKey, "", SeckillOrderVO.class);
        ArrayList<SeckillOrderVO> seckillOrderVOS = new ArrayList<>(soMap.values());

        //更新订单数据中的库存数据
        BaseKeyPrefix stockKey = new BaseKeyPrefix(0, "SECKILL_GOOD_STOCK");
        for (SeckillOrderVO seckillOrderVO : seckillOrderVOS) {
            Integer stockCount = redisService.get(stockKey, seckillOrderVO.getGoodId() + "", Integer.class);
            seckillOrderVO.setStockCount(stockCount >= 0 ? stockCount : 0);
        }

        return seckillOrderVOS;
    }

    /**
     * 根据商品ID 查询
     * @param goodId
     * @return
     */
    @Override
    public SeckillOrderVO findById(Long goodId) {

        List<SeckillOrderVO> seckillOrderVOs = query();
        for (SeckillOrderVO seckillOrderVO : seckillOrderVOs) {
            if (seckillOrderVO.getGoodId() == goodId) {
                return seckillOrderVO;
            }
        }
        return null;
    }

    /**
     * 根据商品ID 递减库存
     * @param goodId
     * @return
     */
    @Override
    public int reduce(Long goodId) {
        return seckillMapper.reduce(goodId);
    }

    /**
     * 根据商品ID 查询商品信息
     * @param goodId
     * @return
     */
    @Override
    public SeckillGood findByGoodId(Long goodId) {

        return seckillMapper.findByGoodId(goodId);
    }

    /**
     * 订单超时,根据订单号,更改订单状态值
     * @param orderNo
     * @return
     */
    @Override
    public int timeOutCancelOrder(String orderNo) {
        return seckillMapper.timeOutCancelOrder(orderNo);
    }

    /**
     * 订单超时,根据商品ID ,回滚MySQL数据,
     * @param goodId
     */
    @Override
    public void updateByGoodId(Long goodId) {
        seckillMapper.updateByGoodId(goodId);
    }



    @Override
    public void goodInit() {
        List<SeckillGood> seckillGoods = seckillMapper.list();

        List<SeckillOrderVO> seckillOrderVOS = new ArrayList<>();
        List<Long> ids = new ArrayList<>();

        for (SeckillGood seckillGood : seckillGoods) {
            SeckillOrderVO seckillOrderVO = new SeckillOrderVO();
            BeanUtils.copyProperties(seckillGood,seckillOrderVO);
            ids.add(seckillGood.getGoodId());
            seckillOrderVOS.add(seckillOrderVO);
        }

        List<Good> goods = null;
        try {
            goods = goodsFeignApi.findByIds(ids);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (goods == null){
            throw new BusinessException(CodeMsg.DEFAULT_ERROR);
        }

        for (Good good : goods) {
            for (SeckillOrderVO seckillOrderVO : seckillOrderVOS) {
                if (seckillOrderVO.getGoodId() == good.getId()) {
                    BeanUtils.copyProperties(good,seckillOrderVO);
                }
            }
        }

        BaseKeyPrefix mapKey = new BaseKeyPrefix(0, "SECKILL_GOOD_HASH");
        BaseKeyPrefix stockKey = new BaseKeyPrefix(0, "SECKILL_GOOD_STOCK");

        for (SeckillOrderVO vo : seckillOrderVOS) {
            redisService.hset(mapKey, "", vo.getId() + "", vo);
            redisService.set(stockKey, vo.getGoodId() + "", vo.getStockCount());
        }

    }

}
